﻿using Aliphant.Mvvm.XEvent.Events.Base.SubScription;

namespace Aliphant.Mvvm.XEvent.Events.Base
{
    public abstract class EventBase
    {
        private List<ISubScriptionToken> _subScriptionList = new List<ISubScriptionToken>();
        protected ICollection<ISubScriptionToken> SubScriptionList => _subScriptionList;

        protected SubScriptionToken OnSubscribe(ISubScriptionToken subScriptionToken)
        {
            lock (SubScriptionList)
            {
                subScriptionToken.SubScription = new SubScriptionToken();
                SubScriptionList.Add(subScriptionToken);
                return subScriptionToken.SubScription;
            }
        }

        protected void OnPublish(params object[] arguments)
        {
            foreach (var item in GetSubscriptionStrategies())
            {
                item(arguments);
            }
        }

        public void UnSubscribe(SubScriptionToken? token)
        {
            if (token == null) return;
            lock (SubScriptionList)
            {
                ISubScriptionToken? subscriptionToken = SubScriptionList.FirstOrDefault(m => m.SubScription == token);
                if (subscriptionToken != null)
                {
                    SubScriptionList.Remove(subscriptionToken);
                }
            }
        }


        private List<Action<object[]>> GetSubscriptionStrategies()
        {
            List<Action<object[]>> list = new List<Action<object[]>>();
            lock (SubScriptionList)
            {
                for (int num = SubScriptionList.Count - 1; num >= 0; num--)
                {
                    Action<object[]>? executionStrategy = _subScriptionList[num].GetExecutionStrategy();
                    if (executionStrategy == null)
                    {
                        _subScriptionList.RemoveAt(num);
                    }
                    else
                    {
                        list.Add(executionStrategy);
                    }
                }
                return list;
            }
        }

    }
}
